package com.ruoyi.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import net.sf.ezmorph.Morpher;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;
import net.sf.json.xml.XMLSerializer;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.*;

public class JsonUtils {
    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MorpherRegistry mr = JSONUtils.getMorpherRegistry();


        DateMorpher dm = new DateMorpher(new String[] { DateUtils.YYYY_MM_DD, DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.HH_MM_ss, DateUtils.YYYYMMDD, DateUtils.YYYYMMDDHHMMSS, DateUtils.HHMMss });


        mr.registerMorpher((Morpher)dm);
    }







    public static Object getDtoFromJsonObjStr(String jsonObjStr, Class clazz) {
        return JSONObject.toBean(JSONObject.fromObject(jsonObjStr), clazz);
    }








    public static Object getDtoFromJsonObjStr(String jsonObjStr, Class clazz, Map classMap) {
        return JSONObject.toBean(JSONObject.fromObject(jsonObjStr), clazz, classMap);
    }






    public static Object[] getArrFromJsonArrStr(String jsonArrStr) {
        return JSONArray.fromObject(jsonArrStr).toArray();
    }







    public static Object[] getDtoArrFromJsonArrStr(String jsonArrStr, Class clazz) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        Object[] objArr = new Object[jsonArr.size()];
        for (int i = 0; i < jsonArr.size(); i++) {
            objArr[i] = JSONObject.toBean(jsonArr.getJSONObject(i), clazz);
        }
        return objArr;
    }









    public static Object[] getDtoArrFromJsonArrStr(String jsonArrStr, Class clazz, Map classMap) {
        JSONArray array = JSONArray.fromObject(jsonArrStr);
        Object[] obj = new Object[array.size()];
        for (int i = 0; i < array.size(); i++) {
            JSONObject jsonObject = array.getJSONObject(i);
            obj[i] = JSONObject.toBean(jsonObject, clazz, classMap);
        }
        return obj;
    }






    public static List getListFromJsonArrStr(String jsonArrStr) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(jsonArr.get(i));
        }
        return list;
    }







    public static List getListFromJsonArrStr(String jsonArrStr, Class clazz) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(JSONObject.toBean(jsonArr.getJSONObject(i), clazz));
        }
        return list;
    }








    public static List getListFromJsonArrStr(String jsonArrStr, Class clazz, Map classMap) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArrStr);
        List<Object> list = new ArrayList();
        for (int i = 0; i < jsonArr.size(); i++) {
            list.add(JSONObject.toBean(jsonArr.getJSONObject(i), clazz, classMap));
        }
        return list;
    }






    public static Map getMapFromJsonObjStr(String jsonObjStr) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<Object, Object> map = new HashMap<>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext(); ) {
            String key = iter.next();
            map.put(key, jsonObject.get(key));
        }
        return map;
    }







    public static Map getMapFromJsonObjStr(String jsonObjStr, Class clazz) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<Object, Object> map = new HashMap<>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext(); ) {
            String key = iter.next();
            map.put(key, JSONObject.toBean(jsonObject.getJSONObject(key), clazz));
        }
        return map;
    }








    public static Map getMapFromJsonObjStr(String jsonObjStr, Class clazz, Map classMap) {
        JSONObject jsonObject = JSONObject.fromObject(jsonObjStr);

        Map<Object, Object> map = new HashMap<>();
        for (Iterator<String> iter = jsonObject.keys(); iter.hasNext(); ) {
            String key = iter.next();
            map.put(key,
                    JSONObject.toBean(jsonObject.getJSONObject(key), clazz, classMap));
        }
        return map;
    }







    public static String getJsonStr(Object obj) {
        String jsonStr = null;

        JsonConfig jsonCfg = new JsonConfig();


        jsonCfg.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor(DateUtils.YYYY_MM_DD));

        jsonCfg.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor(DateUtils.YYYY_MM_DD));

        jsonCfg.registerJsonValueProcessor(Timestamp.class, new DateJsonValueProcessor(DateUtils.YYYY_MM_DD_HH_MM_SS));

        jsonCfg.setIgnoreDefaultExcludes(false); //设置默认忽略
        jsonCfg.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        if (obj == null) {
            return "{}";
        }

        if (obj instanceof Collection || obj instanceof Object[]) {
            jsonStr = JSONArray.fromObject(obj, jsonCfg).toString();
        } else {
            jsonStr = JSONObject.fromObject(obj, jsonCfg).toString();
        }

        return jsonStr;
    }












    public static String getXMLFromObj(Object obj) {
        XMLSerializer xmlSerial = new XMLSerializer();


        JsonConfig jsonCfg = new JsonConfig();


        jsonCfg.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor(DateUtils.YYYY_MM_DD_HH_MM_SS));


        if ((String.class.isInstance(obj) && String.valueOf(obj).startsWith("[")) || obj
                .getClass().isArray() || Collection.class.isInstance(obj)) {
            JSONArray jsonArr = JSONArray.fromObject(obj, jsonCfg);
            return xmlSerial.write((JSON)jsonArr);
        }
        JSONObject jsonObj = JSONObject.fromObject(obj, jsonCfg);
        return xmlSerial.write((JSON)jsonObj);
    }







    public static String getJsonStrFromXML(String xml) {
        XMLSerializer xmlSerial = new XMLSerializer();
        return String.valueOf(xmlSerial.read(xml));
    }



    public static Object getObject4JsonString(String jsonString, Class pojoCalss) {
        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        Object pojo = JSONObject.toBean(jsonObject, pojoCalss);
        return pojo;
    }







    public static Map getMap4Json(String jsonString) {
        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        Iterator<String> keyIter = jsonObject.keys();


        Map<Object, Object> valueMap = new HashMap<>();

        while (keyIter.hasNext()) {
            String key = keyIter.next();
            Object value = jsonObject.get(key);
            valueMap.put(key, value);
        }

        return valueMap;
    }







    public static Object[] getObjectArray4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        return jsonArray.toArray();
    }










    public static List getList4Json(String jsonString, Class pojoClass) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);



        List<Object> list = new ArrayList();
        for (int i = 0; i < jsonArray.size(); i++) {

            JSONObject jsonObject = jsonArray.getJSONObject(i);
            Object pojoValue = JSONObject.toBean(jsonObject, pojoClass);
            list.add(pojoValue);
        }

        return list;
    }








    public static List getListMap4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);

        List<Map<Object, Object>> list = new ArrayList();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            Iterator<String> keyIter = jsonObject.keys();


            Map<Object, Object> valueMap = new HashMap<>();
            while (keyIter.hasNext()) {
                String key = keyIter.next();
                Object value = jsonObject.get(key);
                valueMap.put(key, value);
            }
            list.add(valueMap);
        }
        return list;
    }

    public static String[][] getArray4Json(String jsonString) {
        JSONArray jsonArray1 = JSONArray.fromObject(jsonString);

        String[][] arr = new String[jsonArray1.size()][];
        for (int i = 0; i < jsonArray1.size(); i++) {
            JSONArray jsonArray2 = (JSONArray)jsonArray1.get(i);
            String[] temp = new String[jsonArray2.size()];
            for (int j = 0; j < jsonArray2.size(); j++) {
                temp[j] = jsonArray2.getString(j);
            }
            arr[i] = temp;
        }
        return arr;
    }







    public static String[] getStringArray4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        String[] stringArray = new String[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            stringArray[i] = jsonArray.getString(i);
        }


        return stringArray;
    }









    public static Long[] getLongArray4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Long[] longArray = new Long[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            longArray[i] = new Long(jsonArray.getLong(i));
        }

        return longArray;
    }









    public static Integer[] getIntegerArray4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Integer[] integerArray = new Integer[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            integerArray[i] = new Integer(jsonArray.getInt(i));
        }

        return integerArray;
    }








    public static Double[] getDoubleArray4Json(String jsonString) {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        Double[] doubleArray = new Double[jsonArray.size()];
        for (int i = 0; i < jsonArray.size(); i++) {
            doubleArray[i] = new Double(jsonArray.getDouble(i));
        }

        return doubleArray;
    }










    public static String getJsonString4JavaPOJO(Object javaObj) {
        JSONObject json = JSONObject.fromObject(javaObj);
        return json.toString();
    }








    public static String convertListBySelf(List voArray) {
        if (voArray.size() == 0)
            return "{results:[]}";
        StringBuffer josnsb = new StringBuffer();
        josnsb.append("{results:");
        JSONArray ja = JSONArray.fromObject(voArray);
        josnsb.append(ja.toString());
        josnsb.append("}");
        return josnsb.toString();
    }











    public static String convertListBySelf(int totalCount, List voArray) {
        if (voArray.size() == 0)
            return "{results:[]}";
        StringBuffer josnsb = new StringBuffer();
        josnsb.append("{totalCount:'");
        josnsb.append(totalCount);
        josnsb.append("',results:");
        JSONArray ja = JSONArray.fromObject(voArray);
        josnsb.append(ja.toString());
        josnsb.append("}");
        return josnsb.toString();
    }











    public static String convertToObjectList(String[] rowName, List<Object[]> object) {
        JSONObject json = new JSONObject();
        json.put("lbtotalCount", "");
        if (object == null || object.size() == 0) {
            json.put("results", "");
            return json.toString();
        }
        JSONArray jsonItems = new JSONArray();
        for (int i = 0; i < object.size(); i++) {
            JSONObject itemJson = new JSONObject();
            Object[] obj = object.get(i);
            for (int j = 0; j < rowName.length; j++)
            {
                itemJson.put(rowName[j], ((obj[j] != null) ? obj[j] : "")
                        .toString());
            }
            jsonItems.add(itemJson);
        }
        json.put("results", jsonItems);

        return json.toString();
    }


    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            Gson gson = new Gson();
            String result = gson.toJson(data);
            String string = MAPPER.writeValueAsString(result);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson2(Object data, HttpServletResponse response, Type listType) {
        //如果是Struts2这里可以使用ServletActionContext.getResponse();获取HttpServletResponse对象
        Gson gson = new Gson();
        String result = gson.toJson(data);
        response.setContentType("text/json; charset=utf-8");
        response.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.print(result);
        out.flush();
        out.close();
        return null;
    }


    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson3(Object data,HttpServletResponse response) {
        //如果是Struts2这里可以使用ServletActionContext.getResponse();获取HttpServletResponse对象
        Gson gson = new Gson();
        String result = gson.toJson(data);
        response.setContentType("text/json; charset=utf-8");
        response.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.print(result);
        out.flush();
        out.close();
        return null;
    }

    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    public static void main(String[] args) throws Exception {
        String aa = "[\"2012-04-04\",null,null,null,null]";
        Object[] os = getArrFromJsonArrStr(aa);
        System.out.println(os);
    }
}
